/************************************************************************/
/* Nano Qt OpenCV Serial Multithreaded:                                 */
/* A multithreaded OpenCV application using the Qt framework, that      */
/* controls and processes the data from Nanofiber detection Unit device */
/*                                                                      */
/* FastMatchTemplate.h                                                  */
/*                                                                      */
/* Sergejus Martinenas - SDU 2011                                       */
/*                                                                      */
/*                                                                      */
/* Permission is hereby granted, free of charge, to any person          */
/* obtaining a copy of this software and associated documentation       */
/* files (the "Software"), to deal in the Software without restriction, */
/* including without limitation the rights to use, copy, modify, merge, */
/* publish, distribute, sublicense, and/or sell copies of the Software, */
/* and to permit persons to whom the Software is furnished to do so,    */
/* subject to the following conditions:                                 */
/*                                                                      */
/* The above copyright notice and this permission notice shall be       */
/* included in all copies or substantial portions of the Software.      */
/*                                                                      */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,      */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF   */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND                */
/* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS  */
/* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN   */
/* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN    */
/* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE     */
/* SOFTWARE.                                                            */
/*                                                                      */
/************************************************************************/

#ifndef FastMatchTemplate_h
#define FastMatchTemplate_h


/*
    How fast match template works:
    1. Both target and source image are down sampled numDownPyrs times
    2. cvMatchTemplate() function is called on shrunken images 
       (uses CCORR_NORMED algorithm)
    3. The numMaxima best locations are found
    4. For each point where a maxima was located:
       a) Original source image is searched at point +/- searchExpansion
          pixels in both x and y direction
    5. If match score is above matchPercentage then the location and score is 
       saved in the foundPointsList and confidencesList, respectively
    6. If findMultipleTargets is true, an attempt will be made to find up to
       numMaxima targets
    7. (Optional) The targets can be drawn to a color version of the source 
       image using the DrawFoundTargets() function
 */

#include <stdio.h>
#include <vector>
#include <opencv/cv.h>

using std::vector;

/*=============================================================================
  FastMatchTemplate
  Performs a fast match template
  Returns: true on success, false on failure
  Parameters:
    source - source image (where we are searching)
    target - target image (what we are searching for)
    foundPointsList - contains a list of the points where the target was found
    confidencesList - contains a list of the confidence value (0-100) for each
                      found target
    matchPercentage - the minimum required match score to consider the target
                      found
    findMultipleTargets - if set to true, the function will attempt to find a
                          maximum of numMaxima targets
    numMaxima - the maximum number of search locations to try before exiting
                (i.e. when image is down-sampled and searched, we collect the
                best numMaxima locations - those with the highest confidence -
                and search the original image at these locations)
    numDownPyrs - the number of times to down-sample the image (only increase
                  this number if your images are really large)
    searchExpansion - The original source image is searched at the top locations
                      with +/- searchExpansion pixels in both the x and y 
                      directions
*/
bool 
FastMatchTemplate( const IplImage&  source, 
                   const IplImage&  target,
                   vector<CvPoint>* foundPointsList,
                   vector<double>*  confidencesList,
                   int              matchPercentage = 20,
                   bool             findMultipleTargets = true,
                   int              numMaxima = 5,
                   int              numDownPyrs = 2,
                   int              searchExpansion = 15 );

/*=============================================================================
  MultipleMaxLoc
  Searches an image for multiple maxima
  Assumes a single channel, floating point image
  Parameters:
    image - the input image, generally the result from a cvMatchTemplate call
    locations - array of CvPoint (pass in a NULL point)
    numMaxima - the maximum number of best match maxima to locate
*/
void 
MultipleMaxLoc( const IplImage& image, 
                CvPoint**       locations,
                int             numMaxima );

/*=============================================================================
  DrawFoundTargets
  Draws a rectangle of dimension size, at the given positions in the list,
  in the given RGB color space
  Parameters:
    image - a color image to draw on
    size - the size of the rectangle to draw
    pointsList - a list of points where a rectangle should be drawn
    confidencesList - a list of the confidences associated with the points
    red - the red value (0-255)
    green - the green value (0-255)
    blue - the blue value (0-255)
*/
void
DrawFoundTargets( IplImage*              image,
                  const CvSize&          size,
                  const vector<CvPoint>& pointsList,
                  const vector<double>&  confidencesList,
                  int                    red   = 0,
                  int                    green = 255,
                  int                    blue  = 0 );

/*=============================================================================
  findBrightness
  Finds average brigthness of the selected region in the image, given by
  the point and size
  Parameters:
    image - a color image find brightness of
    point - center point of the region of interest
    size - the size of the rectangle to consider
    side - side of the square to calculate the average brightness from in pixels (default 10)
*/

double findBrigthness(const IplImage& image,
                    const CvPoint point,
                    const CvSize& size,
                    int side = 10
                    );

/*=============================================================================
  calculatePolarization
  Calculates the polarization of the sample based on the three image taken
  with different angles of the polarizer
  Parameters:
    image 1,2,3 - a color images of the sample
    pointList - center point of the region of interest
    size - the size of the rectangle to consider
    angle 1,2,3 - angles of the polarizer at which pictures weer taken
    maxA - calculated maximum Amplitude
    phaseShift - calculated phaseShift of the fiber to the horizontal axis
    noiseLevel - background light noise
*/

void calculatePolarization(const IplImage& image1,
                           const IplImage& image2,
                           const IplImage& image3,
                           const vector<CvPoint>& pointsList,
                           const CvSize& size,
                           double angle1,
                           double angle2,
                           double angle3,
                           double* maxA,
                           double* phaseShift,
                           double* noiseLevel);


IplImage *rotateImage(const IplImage *src, float angleDegrees);

#endif
